package it.allerj.common.persistence;

import it.allerj.common.persistence.clientSide.PersistenceClientHome;

import java.io.Serializable;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.proxy.HibernateProxy;

public class OQLHelper {

	public static Query createQuery(String query) {
		return PersistenceClientHome.getSession().createQuery(query);
	}

	public static Session getSession() {
		return PersistenceClientHome.getSession();
	}

	public static void save(Object obj) {
		HibernateConfigHolder hch = getHibernateConigHolder();
		hch.getSession().save(obj);
	}

	public static void update(Object obj) {
		HibernateConfigHolder hch = getHibernateConigHolder();
		hch.getSession().update(obj);
	}

	public static boolean remove(Object obj, boolean doMerge) {
		Session hsession = getHibernateConigHolder().getSession();
		if (doMerge)
			obj = (PersistenceObject) hsession.merge(obj);
		boolean returnValue = true;
		HibernateConfigHolder hch = getHibernateConigHolder();
		hch.getSession().delete(obj);
		try {
			hch.getSession().flush();
		} catch (HibernateException ex) {
			ex.printStackTrace();
			hch.getTransaction().rollback();
			throw ex;
		}
		return returnValue;
	}

	public static boolean remove(Object obj) {
		return remove(obj, false);
	}

	public static PersistenceObject saveOrUpdate(PersistenceObject obj, boolean doMerge) {
		Session hsession = getHibernateConigHolder().getSession();
		if (obj.getId() != PersistenceObject.UNSAVED_VALUE) {
			if (doMerge)
				obj = (PersistenceObject) hsession.merge(obj);
			hsession.update(obj);
		} else {
			hsession.save(obj);
		}
		// hsession.flush();
		return obj;
	}

	public static PersistenceObject saveOrUpdate(PersistenceObject obj) {
		return saveOrUpdate(obj, true);
	}

	@SuppressWarnings("unchecked")
	public static Object get(String guessedClassName, Serializable key) {
		Object returnObject = null;
		if (key != null)
			try {
				Class guessedClass = Class.forName(guessedClassName.split("\\$\\$")[0]);
				returnObject = getHibernateConigHolder().getSession().get(guessedClass, key);
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
		return returnObject;
	}

	@SuppressWarnings("unchecked")
	public static <T> List<T> getListOf(Class<T> guessedClass) {
		return (List<T>) OQLHelper.getHibernateConigHolder().getSession().createCriteria(guessedClass).list();
	}

	private static HibernateConfigHolder getHibernateConigHolder() {
		HibernateConfigHolder hch = null;

		hch = (HibernateConfigHolder) PersistenceClientHome.getHibernateHolder().get();

		return hch;

		/*
		 * HibernateConfigHolder hch= new HibernateConfigHolder();
		 * hch.setSession(getSession()); return hch;
		 */
	}

	public static void checkPoint() {
		PersistenceClientHome.checkPoint();
	}

	public static void commitAndClose() {
		PersistenceClientHome.commitAndClose();
	}

	public static <T> T deproxy(Object maybeProxy, Class<T> baseClass) throws ClassCastException {
		if (maybeProxy instanceof HibernateProxy)
			return baseClass.cast(((HibernateProxy) maybeProxy).getHibernateLazyInitializer().getImplementation());
		else
			return baseClass.cast(maybeProxy);
	}

}
